C has undefined behaviour
Seriously, Java (more accurately, the Java virtual machine, not the language) imposes a runtime overhead on all programs, in order to detect buffer overruns.
C is not associated with any virtual machine, so a C program is allowed to run over memory, without being forced to stay within array bounds. A segmentation fault (under unix) means the operating system has detected a program accessing some memory that it shouldn't. If the operating system does not detect such things (which is possible, as operating systems do not typically provide 100% coverage either of such things) they will remain undetected.
The trade-off is one of performance versus need for programmer discipline. Java trades off performance in order to capture and report programmer errors. C relies on a programmer to do things right, but - if the programmer does things right - does not impose significant performance overhead.
Note: despite marketing spiels suggesting Java is safe, it is actually technically possible for a buffer overrun to remain undetected in Java (to get a 100% guarantee, it would be necessary to sacrifice a lot more in terms of performance and other attributes). The only difference is that an overrun is more likely to be detected at the point it happens in Java, when compared with C.
In C++, it cannot. In C, this is a meaningless question.
Accessing data past the end of an array is undefined behaviour, in both C and C++. Once you're in the realms of undefined behaviour, there is no guarantee than any feature of the language is even usable. That includes exceptions: there is no means defined in the standard by which an invalid pointer operation causes any exception to be thrown.
As noted above, the onus is on the C and C++ programmer to
prevent or
avoid instances of undefined behaviour, rather than relying on detection of such circumstances. For this reason, there is no standard means of detecting things like buffer overruns.